#include "wsCompress.h"

#include <windows.h>
#include "..\zip\zip.h"
#include "..\zip\unzip.h"

HZIP g_hz;

wsFile::wsFile(TCHAR* fileName, int fileSize)
{
	_tcscpy_s(name, _countof(name), fileName);
	this->size = fileSize;
	this->data = new BYTE[fileSize];
}

wsFile::~wsFile()
{
	delete [] data;
}

wsCompress::wsCompress()
{
}


wsCompress::~wsCompress()
{
}

void wsCompress::compressSample()
{
	HZIP hz;

	// EXAMPLE 1 - create a zipfile from existing files
	hz = CreateZip(_T(".\\simple1.zip"),0);
	ZipAdd(hz,_T("znsimple.bmp"), _T(".\\simple.bmp"));
	ZipAdd(hz,_T("znsimple.txt"), _T(".\\simple.txt"));
	CloseZip(hz);
	_tprintf(_T("Created '\\simple1.zip'\n"));
}

bool wsCompress::extractToFile(const TCHAR* sourceFile, const TCHAR* targetDir)
{
	HZIP hz;

	try
	{
		//hz = OpenZip(_T("D:\\work\\wsLauncher\\wsLauncher\\ziptest.zip"), 0);
		//SetUnzipBaseDir(hz, _T(".\\"));
	
		hz = OpenZip(sourceFile, 0);
		SetUnzipBaseDir(hz, targetDir);
	
		ZIPENTRY ze;
		GetZipItem(hz, -1, &ze);
		int numitems = ze.index;
		for (int zi = 0; zi < numitems; zi++)
		{
			GetZipItem(hz, zi, &ze);

			if( ze.attr & FILE_ATTRIBUTE_DIRECTORY )
			{
				// this is folder.
			}

			if( UnzipItem(hz, zi, ze.name) == ZR_FAILED )
			{
				throw false;
			}
		}

		throw true;
	}
	catch(bool exception)
	{
		CloseZip(hz);
		return exception;
	}
}

wsFile* wsCompress::extractToMemory(const TCHAR* sourceFile, const TCHAR* itemName)
{
	HZIP hz;

	try
	{
		hz = OpenZip(sourceFile, 0);
		SetUnzipBaseDir(hz, _T(".\\"));
	
		ZIPENTRY ze;
		int index;
		FindZipItem(hz, itemName, true, &index, &ze);

		wsFile* file = new wsFile(ze.name, ze.unc_size);
		if( UnzipItem(hz, index, file->data, ze.unc_size) == ZR_FAILED )
		{
			throw NULL;
		}

		throw file;
	}
	catch(wsFile* file)
	{
		CloseZip(hz);
		return file;
	}
}

void wsCompress::openFromResource(const int resourceID)
{
	HINSTANCE hInstance=GetModuleHandle(0);
	HRSRC hrsrc = FindResource(hInstance, MAKEINTRESOURCE(resourceID), RT_RCDATA);
	HANDLE hglob = LoadResource(hInstance, hrsrc);
	void *zipbuf = LockResource(hglob);
	unsigned int ziplen = SizeofResource(hInstance, hrsrc);

	g_hz = OpenZip(zipbuf, ziplen, 0);  
	SetUnzipBaseDir(g_hz,_T("\\"));
}

wsFile* wsCompress::getResourceItem(const TCHAR* itemName)
{
	ZIPENTRY ze;
	int index;
	FindZipItem(g_hz, itemName, true, &index, &ze);

	wsFile* file = new wsFile(ze.name, ze.unc_size);
	UnzipItem(g_hz, index, file->data, ze.unc_size);

	return file;
}

void wsCompress::closeFromResource()
{
	CloseZip(g_hz);
}

//void UnzipWithProgress(const TCHAR *zipfn, HWND hprog)
//{ HZIP hz = OpenZip(zipfn,0);
//  ZIPENTRY ze; GetZipItem(hz,-1,&ze); int numentries=ze.index;
//  // first we retrieve the total size of all zip items
//  DWORD tot=0; for (int i=0; i<numentries; i++) {GetZipItem(hz,i,&ze); tot+=ze.unc_size;}
//  //
//  DWORD countall=0; // this is our progress so far
//  for (int i=0; i<numentries && !abort_p; i++)
//  { GetZipItem(hz,i,&ze);
//    // We'll unzip each file bit by bit, to a file on disk
//    char fn[1024]; wsprintf(fn,"\\z\\%s",ze.name);
//    HANDLE hf = CreateFile(fn,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
//    char buf[16384]; // Each chunk will be 16k big. After each chunk, we show progress
//    DWORD countfile=0;
//    for (ZRESULT zr=ZR_MORE; zr==ZR_MORE && !abort_p; ) // nb. the global "abort_p" flag is set by the user clicking the Cancel button.
//    { zr=UnzipItem(hz,i,buf,16384);
//      unsigned long bufsize=16384; if (zr==ZR_OK) bufsize=ze.unc_size-countfile; // bufsize is how much we got this time
//      DWORD writ; WriteFile(hf,buf,bufsize,&writ,0); 
//      countfile+=bufsize; // countfile counts how much of this file we've unzipped so far
//      countall+=bufsize; // countall counts how much total we've unzipped so far
//      // Now show progress, and let Windows catch up...
//      int i = (int)(100.0*((double)countall)/((double)tot));
//      SendMessage(hprog,PBM_SETPOS,i,0); PumpMessages();
//    }
//    CloseHandle(hf);
//    if (abort_p) DeleteFile(fn);
//  }
//  CloseZip(hz);
//}